package org.anq.ddm.utils;

import com.amazonaws.ClientConfiguration;
import com.amazonaws.Protocol;
import com.amazonaws.SdkClientException;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.AWSCredentialsProvider;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.client.builder.AwsClientBuilder;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.model.*;
import com.amazonaws.util.IOUtils;
import com.amazonaws.util.StringUtils;
import org.anq.ddm.config.AwzS3Config;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.Objects;
import java.util.UUID;

@Component
public class AwzS3Util {

    @Resource
    private AwzS3Config injectAwzS3Config;

    private static AwzS3Config awzS3Config;

    private static AmazonS3 amazonS3;


    @PostConstruct
    public void init() {
        awzS3Config = this.injectAwzS3Config;
        AWSCredentials credentials = new BasicAWSCredentials(awzS3Config.getAccessKey(), awzS3Config.getSecretKey());
        AWSCredentialsProvider credentialsProvider = new AWSStaticCredentialsProvider(credentials);
        AwsClientBuilder.EndpointConfiguration endpointConfig =
                new AwsClientBuilder.EndpointConfiguration(awzS3Config.getUrl(), Regions.CN_NORTH_1.getName());
        ClientConfiguration config = new ClientConfiguration();
        config.setSignerOverride("S3SignerType");
        config.setProtocol(Protocol.HTTP);
        config.withUseExpectContinue(false);
        config.disableSocketProxy();
        amazonS3 = AmazonS3Client.builder()
                .withEndpointConfiguration(endpointConfig)
                .withClientConfiguration(config)
                .withCredentials(credentialsProvider)
                .disableChunkedEncoding()
                .withPathStyleAccessEnabled(true)
                .withForceGlobalBucketAccessEnabled(true)
                .build();
    }


    /**
     * 创建桶
     *
     * @return boolean
     * @params * @param bucket
     * @author susj
     * @date 2022/12/12 16:39
     */
    public static boolean createBucket(String bucket) {
        if (StringUtils.isNullOrEmpty(bucket)) {
            throw new IllegalArgumentException("桶名称不能为空!");
        }
        try {
            amazonS3.createBucket(bucket);
        } catch (SdkClientException e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 删除桶
     *
     * @return boolean
     * @params * @param bucket
     * @author susj
     * @date 2022/12/12 16:39
     */
    public static boolean deleteBucket(String bucket) {
        if (StringUtils.isNullOrEmpty(bucket)) {
            throw new IllegalArgumentException("桶名称不能为空!");
        }
        try {
            amazonS3.deleteBucket(bucket);
        } catch (SdkClientException e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 上传文件
     *
     * @param bucket 桶名称
     * @return boolean
     * @params * @param file
     * @author susj
     * @date 2022/12/12 16:33
     */
    public static String upload(MultipartFile file, String bucket) {
        PutObjectResult result;
        if (Objects.isNull(file)) {
            throw new IllegalArgumentException("文件不能为空!");
        }
        String key = UUID.randomUUID().toString();
        ObjectMetadata objectMetadata = new ObjectMetadata();
        objectMetadata.setContentType(file.getContentType());
        objectMetadata.setContentLength(file.getSize());
        bucket = StringUtils.isNullOrEmpty(bucket) ? awzS3Config.getBucket() : bucket;
        try {
            PutObjectRequest request = new PutObjectRequest(bucket, key, file.getInputStream(), objectMetadata)
                    // 设置文件访问权限
                    .withCannedAcl(CannedAccessControlList.BucketOwnerFullControl);
            result = amazonS3.putObject(request);
        } catch (IOException e) {
            e.printStackTrace();
            return "";
        }
        return key;
    }


    /**
     * 通过文件名称下载
     *
     * @param key
     * @return org.springframework.http.ResponseEntity<byte [ ]>
     * @params * @param bucket
     * @author susj
     * @date 2022/12/12 16:56
     */
    public static ResponseEntity<byte[]> downloadByName(String bucket, String key) throws IOException {
        if (StringUtils.isNullOrEmpty(key)) {
            throw new IllegalArgumentException("文件名称不能为空!");
        }
        bucket = StringUtils.isNullOrEmpty(bucket) ? awzS3Config.getBucket() : bucket;
        GetObjectRequest getObjectRequest = new GetObjectRequest(bucket, key);
        S3Object s3Object = amazonS3.getObject(getObjectRequest);
        S3ObjectInputStream objectInputStream = s3Object.getObjectContent();
        byte[] bytes = IOUtils.toByteArray(objectInputStream);
        // 替换中文
        String showFileName = URLEncoder.encode(key, "UTF-8").replaceAll("\\+", "%20");
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        httpHeaders.setContentLength(bytes.length);
        httpHeaders.setContentDispositionFormData("attachment", showFileName);
        return new ResponseEntity<>(bytes, httpHeaders, HttpStatus.OK);
    }


    /**
     * 删除单个文件
     *
     * @param fileName
     * @return boolean
     * @params * @param bucket
     * @author susj
     * @date 2022/12/12 17:04
     */
    public static boolean deleteFile(String bucket, String fileName) {
        if (StringUtils.isNullOrEmpty(fileName)) {
            throw new IllegalArgumentException("文件名称不能为空!");
        }
        bucket = StringUtils.isNullOrEmpty(bucket) ? awzS3Config.getBucket() : bucket;
        try {
            amazonS3.deleteObject(bucket, fileName);
        } catch (SdkClientException e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 获取文件信息
     *
     * @param fileName
     * @return com.amazonaws.services.s3.model.ObjectMetadata
     * @params * @param bucket
     * @author susj
     * @date 2022/12/12 17:08
     */
    public static ObjectMetadata getFileInfo(String bucket, String fileName) {
        if (StringUtils.isNullOrEmpty(fileName)) {
            throw new IllegalArgumentException("文件名称不能为空!");
        }
        bucket = StringUtils.isNullOrEmpty(bucket) ? awzS3Config.getBucket() : bucket;
        ObjectMetadata objectMetadata = null;
        try {
            objectMetadata = amazonS3.getObjectMetadata(bucket, fileName);
        } catch (SdkClientException e) {
            e.printStackTrace();
        }
        return objectMetadata;
    }
}

